package com.ryskoo.framework.core.controller;

import com.ryskoo.framework.core.bean.*;
import com.ryskoo.framework.core.exception.InvalidParamException;
import com.ryskoo.framework.core.service.IBasicService;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

/**
 * web controller基类
 *
 * @param <PO> the type parameter
 * @author ddy
 */
public class BasicHandler<PO extends BasicPO> {

	/**
	 * 消费者基类
	 */
	private IBasicService basicService;


	/**
	 * 模块的名称，从子类传递过来
	 */
	private String moduleName = "";
	/**
	 * 模块对应的html页面的路径，从子类传递过来
	 */
	private String templatePath = "";

	/**
	 * 基类构造方法.
	 *
	 * @param templatePath 模块对应的html页面的路径
	 * @param moduleName 模块的名称
	 */
	public BasicHandler(String templatePath, String moduleName) {
		this.templatePath = templatePath;
		this.moduleName = moduleName;
	}

	/**
	 * 消费者注入
	 *
	 * @param basicService 消费者基类
	 */
	protected void setService(IBasicService basicService) {
        this.basicService = basicService;
    }

	/**
	 * 跳转列表页
	 *
	 * @return 页面模板路径
	 */
	@GetMapping("/tolist")
	public String toList(Model model, HttpServletRequest request) {
		this.buildListPageData(model, request);
		return templatePath + "/" + moduleName + "List";
	}

	protected void buildListPageData(Model model, HttpServletRequest request) {
	}

	@GetMapping("/toview/{id}")
	public String toView(@PathVariable(value = "id") String id, Model model,HttpServletRequest request) {
        model.addAttribute("dto", basicService.getByUuid(id));
        return templatePath + "/" + moduleName + "View";
	}

	/**
	 * 跳转新增页面
	 *
	 * @param model 页面模型 {@link Model}
	 * @return 页面模板路径
	 */
	@GetMapping("/toadd")
	public String toAdd(Model model, HttpServletRequest request) {
		this.buildAddPageData(model, request);
		return templatePath + "/" + moduleName + "Add";
	}

	/**
	 * 构建新增页面基础数据，子类需重写此方法
	 *
	 * @param model
	 *            页面模型 {@link Model}
	 */
	protected void buildAddPageData(Model model, HttpServletRequest request) {
	}

	/**
	 * 跳转编辑页面
	 *
	 * @param model 页面模型 {@link Model}
	 * @param id 要编辑的实体id，唯一标示
	 * @return 页面模板路径
	 */
	@GetMapping("/toedit/{id}")
	public String toEdit(Model model, @PathVariable(value = "id") String id,  HttpServletRequest request) {
		PO po = (PO)basicService.getByUuid(id);
		model.addAttribute("dto", po);
		this.buildEditPageData(model, po, request);
		return templatePath + "/" + moduleName + "Edit";
	}

	/**
	 * 构建编辑页面基础数据，子类需重写此方法
	 *
	 * @param model 页面模型 {@link Model}
	 * @param po 要编辑的实体id，唯一标示
	 */
	protected void buildEditPageData(Model model, PO po, HttpServletRequest request ) {
	}

	/**
	 * 查询列表
	 * 可以设置查询条件
	 * 可以设置是否分页
	 *
	 * @param qm 统一查询消息 {@link QueryMessageDTO}
	 * @return 统一返回消息 {@link ReturnMessageDTO}
	 */
	@PostMapping("/list")
	@ResponseBody
	public ReturnMessageDTO list(@RequestBody QueryMessageDTO qm) {
		ReturnMessageDTO<List<PO>> returnMessage = new ReturnMessageDTO<>();
		this.buildQueryMessage(qm);
		List<PO> managerList = basicService.queryByConditionAndPage(qm);
		int count = basicService.getCount(qm);
		returnMessage.setReturnCode(ReturnCodeEnum.SUCCESS.getReturnCode());
		returnMessage.setReturnNote("查询成功");
		returnMessage.setReturnMessage(managerList);
		returnMessage.setPager(new Pager(qm.getPageShow(), qm.getStartNum(), count));
        return returnMessage;
	}

	/**
	 * 构建查询条件
	 * @param qm
	 */
	protected void buildQueryMessage(QueryMessageDTO qm) {
	}

	/**
	 * 查询列表
	 * 可以设置查询条件
	 * 不需要分页，根据查询条件查出所有
	 *
	 * @param queryMessage 统一查询消息 {@link QueryMessageDTO}
	 * @return 统一返回消息 {@link ReturnMessageDTO}
	 */
	@PostMapping("/listall")
	@ResponseBody
	public ReturnMessageDTO listAll(@RequestBody QueryMessageDTO queryMessage) {
		ReturnMessageDTO<List<PO>> returnMessage = new ReturnMessageDTO<>();
        List<PO> managerList = basicService.queryByCondition(queryMessage);
        returnMessage.setReturnCode(ReturnCodeEnum.SUCCESS.getReturnCode());
        returnMessage.setReturnNote("查询成功");
        returnMessage.setReturnMessage(managerList);
        return returnMessage;
	}
	
	/**
	 * 根据id查询DTO
	 *
	 * @param id
	 *            DTO的id，唯一标识
	 * @return 对象 {@link PO}
	 */
	@GetMapping("/get/{id}")
	@ResponseBody
	public PO getById(@PathVariable(value = "id") String id) {
		return (PO)basicService.getByUuid(id);
	}

	/**
	 * 新增
	 *
	 * @param po
	 *            新增的对象 {@link PO}
	 * @return 统一返回消息 {@link ReturnMessageDTO}
	 */
	@PostMapping("/add")
	@ResponseBody
	public ReturnMessageDTO add(@RequestBody PO po) {
		ReturnMessageDTO<PO> returnMessage = new ReturnMessageDTO<>();
        try {
            basicService.create(po);
            returnMessage.setReturnCode(ReturnCodeEnum.SUCCESS.getReturnCode());
            returnMessage.setReturnNote("新增成功");
            returnMessage.setReturnMessage(po);
        } catch (InvalidParamException e) {
            returnMessage.setReturnCode(ReturnCodeEnum.FAIL.getReturnCode());
            returnMessage.setReturnNote(e.getMessage());
        } catch (Exception e) {
            returnMessage.setReturnCode(ReturnCodeEnum.ERROR.getReturnCode());
            returnMessage.setReturnNote("新增失败");
        }
        return returnMessage;
	}

	/**
	 * 编辑
	 *
	 * @param po
	 *            编辑的对象 {@link PO}
	 * @return 统一返回消息 {@link ReturnMessageDTO}
	 */
	@PostMapping("/edit")
	@ResponseBody
	public ReturnMessageDTO edit(@RequestBody PO po) {
        ReturnMessageDTO<PO> returnMessage = new ReturnMessageDTO<>();
        try {
            basicService.update(po);
            returnMessage.setReturnCode(ReturnCodeEnum.SUCCESS.getReturnCode());
            returnMessage.setReturnNote("修改成功");
            returnMessage.setReturnMessage(po);
        } catch (InvalidParamException e) {
            returnMessage.setReturnCode(ReturnCodeEnum.FAIL.getReturnCode());
            returnMessage.setReturnNote(e.getMessage());
        } catch (Exception e) {
            returnMessage.setReturnCode(ReturnCodeEnum.ERROR.getReturnCode());
            returnMessage.setReturnNote("修改失败");
        }
        return returnMessage;
	}

	/**
	 * 删除, 支持批量删除
	 *
	 * @param idList
	 *            id列表 {@link List}&lt;{@link String}&gt;
	 * @return 统一返回消息 {@link ReturnMessageDTO}
	 */
	@PostMapping("/delete")
	@ResponseBody
	public ReturnMessageDTO delete(@RequestBody List<String> idList) {
        ReturnMessageDTO<PO> returnMessage = new ReturnMessageDTO<>();
        try {
            basicService.deletes(idList);
            returnMessage.setReturnCode(ReturnCodeEnum.SUCCESS.getReturnCode());
            returnMessage.setReturnNote("删除成功");
        } catch (InvalidParamException e) {
            returnMessage.setReturnCode(ReturnCodeEnum.FAIL.getReturnCode());
            returnMessage.setReturnNote(e.getMessage());
        } catch (Exception e) {
            returnMessage.setReturnCode(ReturnCodeEnum.ERROR.getReturnCode());
            returnMessage.setReturnNote(e.getMessage());
        }
        return returnMessage;
	}
}
